<?php
/*****************************************************************************
 * Copyright (C) 2008-2011 GoalBit Solutions
 * All rights reserved.
 *
 * Authors:   Andres Barrios <andres dot barrios at goalbit-solutions dot com>
 *            Matias Barrios <matias dot barrios at goalbit-solutions dot com>
 *            Daniel De Vera <daniel dot de dot vera at goalbit-solutions dot com>
 *            Pablo Rodriguez Bocca <pablo dot rodriguez dot bocca at goalbit-solutions dot com>
 *            Claudia Rostagnol <claudia dot rostagnol at goalbit-solutions dot com>
 *
 * This file is part of the GoalBit Suite.
 *
 * Commercial License
 * You may use this file in accordance with the terms and conditions
 * contained in the GoalBit Suite End User License and Support
 * Agreement accompanying this package.
 *
 * GNU Affero General Public License version 3
 * Alternatively, this file may be used under the terms of the GNU Affero
 * General Public License version 3 as published by the Free Software
 * Foundation and appearing in the file license.txt included in the
 * packaging of this file.
 *
 * If you have questions regarding the use of this file, please contact
 * GoalBit Solutions <support at goalbit-solutions dot com>.
 *****************************************************************************/
?>
<?php

/*
|--------------------------------------------------------------------------
| GoalbitServicesAPI: Main Class
|--------------------------------------------------------------------------
|
*/

class GoalbitServicesAPI
{
    // Errors
    const STATUS_NO_ERROR       = 0;
    const STATUS_GENERAL_ERROR  = 1;
    const STATUS_API_ERROR      = 2;
    const STATUS_WRONG_PROPERTY = 3;

    // Sort options
    const ORDER_BY_CERTIFICATE_CN    = 1;
    const ORDER_BY_CONTENT_ID        = 2;
    const ORDER_BY_BITRATE           = 3;
    const ORDER_BY_STREAMING_ACTIVE  = 4;
    const ORDER_BY_STREAMING_PLAYING = 5;
    const ORDER_BY_REGDATE           = 6;

    const ORDER_BY_VIDEO_ID          = 10;
    const ORDER_BY_VIDEO_DATE        = 11;
    const ORDER_BY_VIDEO_DELDATE     = 12;

    // Sort Orders
    const SORT_ORDER_ASC  = 1;
    const SORT_ORDER_DESC = 2;

    // Certificate types
    const BRANCH_CERTIFICATE = 1;
    const USER_CERTIFICATE   = 2;

    // Content filters
    const ALL_CONTENT    = 1;
    const BRANCH_CONTENT = 2;
    const USER_CONTENT   = 3;

    //Streaming services
    const DEFAULT_STREAMING_SERVICE = 'http-flash-streaming';


    private $x509cafile   = NULL;
    private $x509certfile = NULL;
    private $x509keyfile  = NULL;
    private $url_services = 'https://local-suite.goalbit-solutions.com:10100/services_api/';


    /* Private Methods ----------------------------------------------------- */


    private function _call_web_method( $webservice_url, $post_args = NULL )
    {
        $session = curl_init($webservice_url);

        curl_setopt( $session, CURLOPT_HEADER, false );
        curl_setopt( $session, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $session, CURLOPT_CONNECTTIMEOUT, 5 );

        if ( !is_null($post_args) )
        {
            curl_setopt ($session, CURLOPT_POST, true);
            curl_setopt ($session, CURLOPT_POSTFIELDS, json_encode($post_args) );
        }

        if ( !is_null($this->x509certfile) && !is_null($this->x509keyfile) )
        {
            if ( !is_null($this->x509cafile) )
                curl_setopt( $session, CURLOPT_CAINFO, $this->x509cafile );

            curl_setopt( $session, CURLOPT_SSL_VERIFYPEER, true );
            curl_setopt( $session, CURLOPT_SSL_VERIFYHOST, 1 );
            //curl_setopt( $session, CURLOPT_SSL_VERIFYHOST, 2 );
            curl_setopt( $session, CURLOPT_SSLCERT, $this->x509certfile );
            curl_setopt( $session, CURLOPT_SSLKEY, $this->x509keyfile );
        }

        $response = curl_exec($session);

        $curl_error = NULL;
        if ( curl_errno($session) )
            $curl_error = curl_error($session);

        curl_close($session);

        if ( $curl_error !== NULL )
            throw new GoalbitServicesAPIError( $this, self::STATUS_API_ERROR, $curl_error);

        return json_decode($response, true);

    }


    private function _check_response ( $response )
    {
        if ( !is_array($response) )
            throw new GoalbitServicesAPIError( $this, self::STATUS_GENERAL_ERROR );
        elseif ( !isset($response['status']) )
            throw new GoalbitServicesAPIError( $this, self::STATUS_GENERAL_ERROR );
        elseif ( $response['status'] != self::STATUS_NO_ERROR )
        {
            if ( isset($response['status_msg']) )
                throw new GoalbitServicesAPIError( $this, self::STATUS_API_ERROR, $response['status_msg'] );
            else
                throw new GoalbitServicesAPIError( $this, self::STATUS_API_ERROR );
        }

        return $this->_decode_responce($response['response']);
    }


    private function _decode_responce ( $response )
    {
        if ( is_array($response) )
        {
            foreach ( $response as $key => $value )
                $decoded_response[$key] = $this->_decode_responce($value);
        }
        else
        {
            if ( substr($response, 0, strlen('data:base64,')) == 'data:base64,' )
            {
                // Base64 data
                $decoded_response = substr($response, strlen('data:base64,'));
                $decoded_response = base64_decode($decoded_response);
            }
            else
                $decoded_response = $response;
        }

        return $decoded_response;
    }


    /* Public Methods ------------------------------------------------------ */


    public function __construct( $x509cafile, $x509certfile, $x509keyfile )
    {
        $this->x509cafile   = $x509cafile;
        $this->x509certfile = $x509certfile;
        $this->x509keyfile  = $x509keyfile;
    }


    public function __set($key, $value)
    {
        if ( isset($this->$key) || is_null($this->$key) )
            $this->$key = $value;
        else
            throw new GoalbitServicesAPIWrongProperty( $this, self::STATUS_WRONG_PROPERTY );
    }


    public function __get($key)
    {
        if( isset($this->$key) || is_null($this->$key) )
            return $this->$key;
        else
            throw new GoalbitServicesAPIWrongProperty( $this, self::STATUS_WRONG_PROPERTY );
    }


    public function get_string_error( $err_code )
    {
        switch($err_code)
        {
            case self::STATUS_GENERAL_ERROR:
                return 'General error';
                break;

            case self::STATUS_API_ERROR:
                return 'API error';
                break;

            case self::STATUS_WRONG_PROPERTY:
                return 'Requested property not found';
                break;
        }
    }



/////////////////// Live ///////////////////////////////////////////

    public function find_all_signals ( $content_type = self::ALL_CONTENT, $page_size = 20, $page_number = 0,
                                       $sort_by = self::ORDER_BY_CONTENT_ID, $sort_order = self::SORT_ORDER_ASC, $get_item_count = 1 )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/find_all_signals/'. $content_type .'/'. $page_size .'/'. $page_number .'/'. $sort_by .'/'. $sort_order .'/'. $get_item_count;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function find_signals_by_cn ( $content_type = self::ALL_CONTENT, $signal_cn, $page_size = 20, $page_number = 0,
                                         $sort_by = self::ORDER_BY_CONTENT_ID, $sort_order = self::SORT_ORDER_ASC, $get_item_count = 1 )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/find_signals_by_cn/'. $content_type .'/'. $signal_cn .'/'. $page_size .'/'. $page_number .'/'. $sort_by .'/'. $sort_order .'/'. $get_item_count;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function update_signal_status( $signal_id, $signal_status )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/update_signal_status';

        $post_params['signal_id']     = $signal_id;
        $post_params['signal_status'] = $signal_status;

        $response = $this->_call_web_method( $webservice_url, $post_params );
        return $this->_check_response( $response );
    }


    public function create_signal( $xmltv_id, $sign_active = 0, $auth_active = 1)
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/create_signal';

        $post_params['xmltv_id'] = $xmltv_id;
		$post_params['sign_active']    = $sign_active;
		$post_params['auth_active']    = $auth_active;

        $response = $this->_call_web_method( $webservice_url, $post_params );
        return $this->_check_response( $response );
    }


    public function get_signal_credentials ( $signal_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/get_signal_credentials/'. $signal_id;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function get_streaming_url ( $signal_id, $user_ip, $streaming_type = 'goalbit', $user_id = '', $tracking_ref = '' )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/get_streaming_url/'. $signal_id .'/'. $user_ip .'/'. $streaming_type .'/'. $user_id .'/'. $tracking_ref ;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function get_signal_thumbs ( $signal_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/get_signal_thumbs/'. $signal_id ;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function get_signal_thumb ( $signal_id, $thumb_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/get_signal_thumb/'. $signal_id .'/'. $thumb_id ;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function get_web_broadcast_data( $signal_id, $user_id, $user_ip )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/get_web_broadcast_data/'. $signal_id .'/'. $user_id .'/'. $user_ip;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function create_certificate( $certificate_type, $user_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/create_certificate/'. $certificate_type .'/'. $user_id;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function create_channel_conf( $certificate_cn, $xmltv_id, $sign_active = 0, $streaming=0 , $auth_active=1 )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/create_channel_conf';

        $post_params['certificate_cn'] = $certificate_cn;
        $post_params['xmltv_id']       = $xmltv_id;
        $post_params['sign_active']    = $sign_active;
        $post_params['auth_active']    = $auth_active;
        $post_params['streaming'] = $streaming;

        $response = $this->_call_web_method( $webservice_url, $post_params );
        return $this->_check_response( $response );
    }


    // $query_info structure:
    //
    //  Time Range:
    //      $query_info['start_date'] : DATETIME format
    //      $query_info['end_date']   : DATETIME format
    //
    //  Filters:
    //      $query_info['filter_types']['content_id']   : [ARRAY|STRING|INT]
    //      $query_info['filter_types']['technology']   : [ARRAY|STRING|INT]
    //      $query_info['filter_types']['country']      : [ARRAY|STRING|INT]
    //      $query_info['filter_types']['tracking_ref'] : [ARRAY|STRING|INT]
    //
    //  Group by:
    //      $query_info['groupby_type'] : (time, content_id, technology, country, tracking_ref)
    //
    public function get_live_custom_stats( $query_info )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'live_content/get_custom_stats';

        $post_params['query_info'] = $query_info;

        $response = $this->_call_web_method( $webservice_url, $post_params );
        return $this->_check_response( $response );
    }


/////////////////// VoD ////////////////////////////////////////////


    public function find_all_videos ( $page_size = 20, $page_number = 0, $sort_by = self::ORDER_BY_VIDEO_ID,
                                       $sort_order = self::SORT_ORDER_DESC, $get_item_count = 1 )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/find_all_videos/'. $page_size .'/'.$page_number .'/'.$sort_by .'/'.$sort_order .'/'. $get_item_count;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function find_videos_by_keyword ( $video_word, $page_size = 20, $page_number = 0, $sort_by = self::ORDER_BY_VIDEO_ID,
                                       $sort_order = self::SORT_ORDER_DESC, $get_item_count = 1 )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/find_videos_by_keyword/'. $video_word .'/'. $page_size .'/'. $page_number .'/'. $sort_by .'/'. $sort_order .'/'. $get_item_count;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function find_new_videos ( $date, $page_size = 20, $page_number = 0, $sort_by = self::ORDER_BY_VIDEO_DATE,
                                       $sort_order = self::SORT_ORDER_DESC, $get_item_count = 1 )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/find_new_videos/'. $date .'/'. $page_size .'/'.
                            $page_number .'/'. $sort_by .'/'. $sort_order .'/'. $get_item_count;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function find_deleted_videos ( $date, $page_size = 20, $page_number = 0, $sort_by = self::ORDER_BY_VIDEO_DELDATE,
                                       $sort_order = self::SORT_ORDER_DESC, $get_item_count = 1 )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/find_deleted_videos/'. $date .'/'. $page_size .'/'.
                            $page_number .'/'. $sort_by .'/'. $sort_order .'/'. $get_item_count;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function find_userIP_videos ( $user_ip, $page_size = 20, $page_number = 0, $sort_by = self::ORDER_BY_VIDEO_DATE,
                                       $sort_order = self::SORT_ORDER_DESC, $get_item_count = 1 )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/find_userIP_videos/'. $user_ip .'/'. $page_size .'/'.
                            $page_number .'/'. $sort_by .'/'. $sort_order .'/'. $get_item_count;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function find_userID_videos ( $user_id, $page_size = 20, $page_number = 0, $sort_by = self::ORDER_BY_VIDEO_DATE,
                                       $sort_order = self::SORT_ORDER_DESC, $get_item_count = 1 )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/find_userID_videos/'. $user_id .'/'. $page_size .'/'.
                            $page_number .'/'. $sort_by .'/'. $sort_order .'/'. $get_item_count;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }



    public function get_upload_video_url ( $user_ip, $user_id = '', $tracking_ref = '' )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/get_vod_upload_URL/'. $user_ip .'/'. $user_id .'/'. $tracking_ref ;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function get_transaction_info ( $transaction_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/get_transaction_info/'. $transaction_id;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function get_video_info ( $video_id, $streaming_profile = GoalbitServicesAPI::DEFAULT_STREAMING_SERVICE )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/get_video_info/'. $video_id .'/'. $streaming_profile;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function remove_video( $video_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/remove_video/'. $video_id;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function set_video_authorization( $video_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/set_video_authorization/'. $video_id;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function unset_video_authorization( $video_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/unset_video_authorization/'. $video_id;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function get_vod_streaming_url ( $video_id, $user_ip, $streaming_service_id = GoalbitServicesAPI::DEFAULT_STREAMING_SERVICE, $user_id = '', $tracking_ref = '' )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/get_streaming_url/'. $video_id .'/'. $user_ip .'/'. $streaming_service_id .'/'. $user_id .'/'. $tracking_ref ;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function get_video_thumbs( $video_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/get_video_thumbs/'. $video_id;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function get_video_thumbs_without_content( $video_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/get_video_thumbs_without_content/'. $video_id;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    public function get_video_thumb( $video_id, $thumb_id )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/get_video_thumb/'. $video_id . '/' . $thumb_id;

        $response = $this->_call_web_method( $webservice_url );
        return $this->_check_response( $response );
    }


    // $query_info structure:
    //
    //  Time Range:
    //      $query_info['start_date'] : DATETIME format
    //      $query_info['end_date']   : DATETIME format
    //
    //  Filters:
    //      $query_info['filter_types']['content_id']   : [ARRAY|STRING|INT]
    //      $query_info['filter_types']['technology']   : [ARRAY|STRING|INT]
    //      $query_info['filter_types']['country']      : [ARRAY|STRING|INT]
    //      $query_info['filter_types']['tracking_ref'] : [ARRAY|STRING|INT]
    //
    //  Group by:
    //      $query_info['groupby_type'] : (time, content_id, technology, country, tracking_ref)
    //
    public function get_vod_custom_stats( $query_info )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'vod_content/get_custom_stats';

        $post_params['query_info'] = $query_info;

        $response = $this->_call_web_method( $webservice_url, $post_params );
        return $this->_check_response( $response );
    }


/////////////////// Events ////////////////////////////////////////////


    // $cant_max: maximum number of events to return.
    //            if empty, all events are returned.
    //
    // $event_types: ARRAY of values in ('live', 'vod', 'vod_thumb')
    //              if empty, all event types are returned.
    //
	public function get_backend_events( $ticket, $cant_max = 0, $event_types = array() )
    {
        $webservice_url  = $this->url_services;
        $webservice_url .= 'backend_event/get_backend_events';

        $post_params['ticket']      = $ticket;
        $post_params['cant_max']    = $cant_max;
        $post_params['event_types'] = $event_types;

        $response = $this->_call_web_method( $webservice_url, $post_params );
        return $this->_check_response( $response );
	}


}


/*
|--------------------------------------------------------------------------
| Auxiliar Classes:
|--------------------------------------------------------------------------
|
*/


class GoalbitServicesAPIException extends Exception
{

    public function __construct( GoalbitServicesAPI $obj, $err_code, $raw_error_string = NULL )
    {
        $error = $obj->get_string_error($err_code);

        if( isset($raw_error_string) )
        {
            $error .= ".\nDetails: ";
            $error .= $raw_error_string ."\n";
        }

        parent::__construct($error, $err_code);
    }


    public function get_message()
    {
        return $this->message;
    }
}

class GoalbitServicesAPIWrongProperty extends GoalbitServicesAPIException{}
class GoalbitServicesAPIError extends GoalbitServicesAPIException{}

?>